package edu.gzy.rpsm_property.service;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import edu.gzy.rpsm_property.mapper.PayMapper;
import edu.gzy.rpsm_property.mapper.RoomMapper;
import edu.gzy.rpsm_property.pojo.Amount;
import edu.gzy.rpsm_property.pojo.PageResult;
import edu.gzy.rpsm_property.pojo.Pay;
import edu.gzy.rpsm_property.pojo.vo.PayInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.List;

@Service
public class PayServiceImpl implements PayService{
    @Autowired
    private PayMapper payMapper;
    @Autowired
    private RoomMapper roomMapper;

    @Override
    public PageResult<PayInfo> pageOfPayInfo(Integer current, Integer size, LocalDate start, LocalDate end,
                                             String username, String idCard, Integer floorId, Integer buildingId) {
        PageHelper.startPage(current,size);
        Page<PayInfo> page = payMapper.selectPayInfoOnCondition(start,end,username,idCard,floorId,buildingId);
        return PageResult.restPage(page);
    }

    @Override
    @Transactional
    public Integer insertUnpaid(Amount amount) throws DuplicateKeyException {
        try {
            // 执行插入操作
            int rowsAffected = payMapper.insertAmount(amount);

            if (rowsAffected > 0) {
                // 插入成功，返回影响的行数
                return rowsAffected;
            } else {
                // 插入失败
                throw new RuntimeException("插入未支付费用信息失败，未影响任何行");
            }
        } catch (DuplicateKeyException e) {
            // 如果是重复主键异常，抛出给调用者
            throw new DuplicateKeyException("新增未支付费用信息失败：重复记录");
        } catch (Exception e) {
            // 其他异常
            throw new RuntimeException("新增未支付费用信息失败", e);
        }
    }

    @Override
    @Transactional
    public void handlePayment(Integer roomId, Integer paymentAmount, Integer payType) {
        if (roomId == null || paymentAmount == null || paymentAmount <= 0 || payType == null) {
            throw new IllegalArgumentException("无效的支付参数");
        }

        try {
            // Step 1: 获取总欠费金额
            Integer totalUnpaidAmount = payMapper.getTotalUnpaidAmountByRoomAndType(roomId, payType);
            if (totalUnpaidAmount == null || totalUnpaidAmount == 0) {
                throw new IllegalStateException("当前没有需要支付的欠费记录");
            }

            // Step 2: 校验支付金额是否超出欠费总额
            if (paymentAmount > totalUnpaidAmount) {
                throw new IllegalStateException("支付金额超出欠费总额。总欠费：" + totalUnpaidAmount + "，支付金额：" + paymentAmount);
            }

            // Step 3: 插入支付记录
            Pay pay = new Pay();
            pay.setPay_room_id(roomId);
            pay.setPay(paymentAmount);
            pay.setPay_type(payType);
            pay.setPay_date(LocalDate.now());
            payMapper.insertPayment(pay);

            // Step 4: 更新欠费记录
            List<Amount> unpaidAmounts = payMapper.findUnpaidAmountsByRoomAndType(roomId, payType);

            for (Amount amount : unpaidAmounts) {
                if (paymentAmount <= 0) {
                    break; // 支付完成，跳出循环
                }

                Integer remainingAmount = amount.getAmount() - paymentAmount;

                if (remainingAmount <= 0) {
                    // 全额支付，更新状态为已支付
                    amount.setAmount(0);
                    amount.setIsPaid(1);
                    paymentAmount = -remainingAmount; // 继续支付下一笔欠费
                } else {
                    // 部分支付，更新剩余金额
                    amount.setAmount(remainingAmount);
                    amount.setIsPaid(2); // 确保状态为未支付
                    paymentAmount = 0;
                }
                payMapper.updateAmount(amount);
            }
        } catch (IllegalStateException e) {
            // 针对校验错误的特殊处理
            throw e;
        } catch (Exception e) {
            // 记录日志，便于排查问题
            throw new RuntimeException("处理支付事务失败", e);
        }
    }


}
